﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Web.UI.WebControls;
using System.Collections;
using System.Web;
using System.Web.SessionState;
using System.Web.Configuration;
using System.IO;
using System.ComponentModel;
using System.Security;
using System.Security.Principal;
using System.Security.Permissions;
using System.Web.Security;
using com.tiyma.common;

namespace com.tiyma.httpmoudle
{
    public class AuthenticateModule : IHttpModule
    {
        public static readonly string CONTEXT_ROLE_KEY = "__CONTEXT_ROLE_KEY__";

        public void Init(HttpApplication ctx)
        {
            ctx.AuthenticateRequest += new EventHandler(context_AuthenticateHandler);
            ctx.EndRequest += new EventHandler(ctx_EndRequest);
        }

        public void Dispose() { }

        /// <summary>
        /// Authentication Event Handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void context_AuthenticateHandler(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
            //LogHelper.Info("IsAuthenticated=" + app.Request.IsAuthenticated);
            //LogHelper.Info("FormsIdentity=" + FormsAuthentication.FormsCookieName);
            if (app.Request.IsAuthenticated && app.User.Identity != null)
            {
                //给用户授于某个角色的权限	
                FormsIdentity id = app.User.Identity as FormsIdentity;
                if (id != null)
                {
                    HttpRequest req = HttpContext.Current.Request;
                    string roleString = "";
                    string cookieName = FormsAuthentication.FormsCookieName;//取得Form认证cookie
                    HttpCookie authCookie = req.Cookies[cookieName];
                    if (null == authCookie)
                    {
                        //There is no authentication cookie.
                        //LogHelper.Info( "cookie is null" );
                        return;
                    }
                    else
                    {
                        //LogHelper.Info( "cookie="+authCookie.Value );
                    }
                    FormsAuthenticationTicket authTicket = null; //取得认证票
                    try
                    {
                        authTicket = FormsAuthentication.Decrypt(authCookie.Value);//解密认证票
                        //if (authTicket.Expired)   //判断是否过期
                        //    return ; 
                    }
                    catch (Exception ex)
                    {
                        //ExceptionManager.Publish( ex );
                        throw;
                    }
                    if (null == authTicket)
                    {
                        //LogHelper.Info( "ticket is null" );
                        return;
                    }
                    else
                    {
                        roleString = authTicket.UserData;//取得角色信息
                        #region deleted
                        //  LogHelper.Info( "ticket ="+roleString );
                        //StringBuilder sb = new StringBuilder();
                        //    sb.Append( "HTTP_CLIENT_IP_1:" + HttpContext.Current.Request.ServerVariables["HTTP_CLIENT_IP"] );
                        //    sb.Append( "\r\n HTTP_X_FORWARDED_FOR_1:" + HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] );
                        //    sb.Append( "   UserTueIp:" + SystemUtility.UserTrueIp );
                        //     sb.Append( "HTTP_VIA2:" + HttpContext.Current.Request.ServerVariables["HTTP_VIA"] );
                        //    LogHelper.Info( sb.ToString() );

                        //if (!UserToken.CheckIp( roleString ))
                        //{
                        //    LogHelper.Info( "HTTP_X_FORWARDED_FOR_2:" + HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] );

                        //    LogHelper.Error( roleString );
                        //    //FormsAuthentication.SignOut();
                        //    //return;
                        //}
                        //else
                        //{
                        //    LogHelper.Info( "CheckIPOK2" );
                        //}
                        #endregion
                    }

                    FormsAuthenticationTicket newTK = FormsAuthentication.RenewTicketIfOld(authTicket);
                    if (!newTK.Equals(authTicket))
                    {
                        //FormsAuthentication.SignOut();
                        //return;                        
                        //* 不再更新Cookie,否则可能造成代理服务器缓存Set-Cookie头 by lzh 2008-3-7
                        HttpCookie newCookie = new HttpCookie(cookieName, FormsAuthentication.Encrypt(newTK));
                        if (!String.IsNullOrEmpty(AppConfig.Domain))
                        {
                            newCookie.Domain = AppConfig.Domain;
                        }
                        HttpContext.Current.Response.Cookies.Add(newCookie);
                    }
                    //保存用户信息
                    if (roleString != null && roleString != string.Empty)
                    {
                        //string role = roleString.Replace("|", ",");
                        string[] arr = null;
                        string[] roles = null;

                        if (roleString.IndexOf("|") > 0)
                        {
                            arr = roleString.Split(new char[] { '|' });

                            if (arr.Length < 4)
                            {
                                LogHelper.Error("roleString=" + roleString + "  TokenString=" + roleString + "     ArrayLen=" + arr.Length);
                            }
                          
                            //把用户帐号信息保存HttpContext中，以备后来使用
                            HttpContext.Current.Items[AuthenticateModule.CONTEXT_ROLE_KEY] = UserToken.ParseToken(arr);
                        }
                        else
                        {
                            roles = new string[] { roleString };
                        }
                        IPrincipal principal = new GenericPrincipal(id, roles);
                        HttpContext.Current.User = principal;
                    }
                    else
                    {
                        // SDAppLog.WriteTrace( "user:" + app.User.Identity.Name + " Role is null" );
                    }
                }
            }
        }
        /// <summary>
        /// Authentication Event Handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ctx_EndRequest(object sender, EventArgs e)
        {
            //Look for an outgoing cookie named "ASP.NET_SessionID"            
            //HttpRequest request = ((HttpApplication)sender).Request;
            HttpCookie cookie = GetCookie(((HttpApplication)sender).Response, "ASP.NET_SessionId");
            if (cookie != null)
            {
                if (!string.IsNullOrEmpty(AppConfig.Domain))
                    cookie.Domain = AppConfig.Domain;
            }
        }


        private HttpCookie GetCookie(HttpResponse response, string name)
        {
            HttpCookieCollection cookies = response.Cookies;
            return FindCookie(cookies, name);
        }

        private HttpCookie FindCookie(HttpCookieCollection cookies, string name)
        {
            int count = cookies.Count;
            for (int i = 0; i < count; i++)
            {
                if (String.Compare(cookies[i].Name, name, true) == 0)
                    return cookies[i];
            }
            return null;
        }
    }
}
